home *** CD-ROM | disk | FTP | other *** search
Wrap
function FindLineIntersections(rayOrigin, rayDirection, circleCenter, circleRadius) { var resultPoints = new Array(); var kDiff = new Object(); kDiff.x = rayOrigin.x - circleCenter.x; kDiff.y = rayOrigin.y - circleCenter.y; var fA0 = kDiff.x * kDiff.x + kDiff.y * kDiff.y - circleRadius * circleRadius; var fA1 = rayDirection.x * kDiff.x + rayDirection.y * kDiff.y; var fA2 = rayDirection.x * rayDirection.x + rayDirection.y * rayDirection.y; var fDiscr = fA1 * fA1 - fA0 * fA2; if(fDiscr > 0) { var fInvA2 = 1 / fA2; fDiscr = Math.sqrt(fDiscr); resultPoints[0] = (- fA1 - fDiscr) * fInvA2; resultPoints[1] = (- fA1 + fDiscr) * fInvA2; } else if(fDiscr == 0) { resultPoints[0] = (- fA1) / fA2; } return resultPoints; } function FindRayCircleIntersections(rkRay, rkCircle) { var resultIntersections = FindLineIntersections(rkRay.origin,rkRay.direction,rkCircle.center,rkCircle.radius); var intersectionPoints = new Array(); if(resultIntersections.length) { if(resultIntersections.length == 1) { if(resultIntersections[0] < 0) { resultIntersections.splice(0); } } else if(resultIntersections[1] < 0) { resultIntersections.splice(0); } else if(resultIntersections[0] < 0) { resultIntersections[0] = resultIntersections[1]; resultIntersections.pop(); } var i = 0; while(i < resultIntersections.length) { intersectionPoints[i] = new Object(); intersectionPoints[i].x = rkRay.origin.x + resultIntersections[i] * rkRay.direction.x; intersectionPoints[i].y = rkRay.origin.y + resultIntersections[i] * rkRay.direction.y; i++; } } return intersectionPoints; } function ArcContainsPoint(rkArc, P) { var angleToP = Math.atan2(P.y - rkArc.center.y,P.x - rkArc.center.x) / 3.141592653589793 * 180; var contains = Math.abs(angleToP - rkArc.angularMidpoint) <= rkArc.arcLength * 0.5; if(!contains) { angleToP = Wrap(angleToP,0,360); var angularMidpoint = Wrap(rkArc.angularMidpoint,0,360); return Math.abs(angleToP - angularMidpoint) <= rkArc.arcLength * 0.5; } return contains; } function FindRayArcIntersections(rkRay, rkArc) { var resultIntersections = FindLineIntersections(rkRay.origin,rkRay.direction,rkArc.center,rkArc.radius); var intersectionPoints = new Array(); if(resultIntersections.length) { if(resultIntersections.length == 1) { if(resultIntersections[0] < 0) { resultIntersections.splice(0); } } else if(resultIntersections[1] < 0) { resultIntersections.splice(0); } else if(resultIntersections[0] < 0) { resultIntersections[0] = resultIntersections[1]; resultIntersections.pop(); } var iResultPoints = 0; var i = 0; while(i < resultIntersections.length) { intersectionPoints[iResultPoints] = new Object(); intersectionPoints[iResultPoints].x = rkRay.origin.x + resultIntersections[i] * rkRay.direction.x; intersectionPoints[iResultPoints].y = rkRay.origin.y + resultIntersections[i] * rkRay.direction.y; if(ArcContainsPoint(rkArc,intersectionPoints[iResultPoints])) { iResultPoints++; } else { intersectionPoints[iResultPoints] = null; } i++; } } return intersectionPoints; } function FindSegmentArcIntersections(rkSegment, rkArc) { var resultIntersections = FindLineIntersections(rkSegment.origin,rkSegment.direction,rkArc.center,rkArc.radius); var intersectionInfo = null; if(resultIntersections.length) { if(resultIntersections.length == 1) { if(resultIntersections[0] < 0 || resultIntersections[0] > 1) { } } else if(resultIntersections[1] < 0 || resultIntersections[0] > 1) { resultIntersections.splice(0); } else if(resultIntersections[1] <= 1) { if(resultIntersections[0] < 0) { resultIntersections[0] = resultIntersections[1]; resultIntersections.pop(); } } else if(resultIntersections[0] >= 0) { resultIntersections.pop(); } else { resultIntersections.splice(0); } var i = 0; while(i < resultIntersections.length) { intersectionInfo = new Object(); intersectionInfo.touchTime = resultIntersections[i] * 0.9; intersectionInfo.touchPoint = new Object(); intersectionInfo.touchPoint.x = rkSegment.origin.x + resultIntersections[i] * rkSegment.direction.x * 0.9; intersectionInfo.touchPoint.y = rkSegment.origin.y + resultIntersections[i] * rkSegment.direction.y * 0.9; if(ArcContainsPoint(rkArc,intersectionInfo.touchPoint)) { break; } intersectionInfo = null; i++; } } return intersectionInfo; } function FindSegmentCircleIntersections(rkSegment, rkCircle) { var resultIntersections = FindLineIntersections(rkSegment.origin,rkSegment.direction,rkCircle.center,rkCircle.radius); var intersectionInfo = null; if(resultIntersections.length) { if(resultIntersections.length == 1) { if(resultIntersections[0] < 0 || resultIntersections[0] > 1) { } } else if(resultIntersections[1] < 0 || resultIntersections[0] > 1) { resultIntersections.splice(0); } else if(resultIntersections[1] <= 1) { if(resultIntersections[0] < 0) { resultIntersections[0] = resultIntersections[1]; resultIntersections.pop(); } } else if(resultIntersections[0] >= 0) { resultIntersections.pop(); } else { resultIntersections.splice(0); } var i = 0; while(i < resultIntersections.length) { intersectionInfo = new Object(); intersectionInfo.touchTime = resultIntersections[i] * 0.9; intersectionInfo.touchPoint = new Object(); intersectionInfo.touchPoint.x = rkSegment.origin.x + resultIntersections[i] * rkSegment.direction.x * 0.9; intersectionInfo.touchPoint.y = rkSegment.origin.y + resultIntersections[i] * rkSegment.direction.y * 0.9; i++; } } return intersectionInfo; } function CPaddle() { this._score = 0; if(this._isAIControlled) { this.onEnterFrame = this.PerformAI; } else { this.onEnterFrame = this.UpdateRotation; this._rotationTarget = new Object(); } this._englishAngle = 0; } function IsRightOfHumpLine(angle, buffer) { if(angle + buffer > 120 && angle - buffer < 150) { return undefined; } return angle + buffer <= 120 && angle - buffer > -60; } function IsLeftOfHumpLine(angle, buffer) { if(angle + buffer > 120 && angle - buffer < 150) { return undefined; } return angle - buffer >= 150 || angle + buffer < -30; } CPaddle.prototype = new MovieClip(); Object.registerClass("CPaddle",CPaddle); CPaddle.prototype.Score = function() { this._score = this._score + 1; }; CPaddle.prototype.ScoreFailure = function() { this._score--; }; CPaddle.prototype.UpdateRotation = function() { if(this._rotationTarget) { var desiredRotation = this._rotationTarget + this._englishAngle; var currentRotation = WrapAngle(this._rotation + 45); desiredRotation = WrapAngle(desiredRotation + 45); var deltaRotation = desiredRotation - currentRotation; var deltaRotationSign = deltaRotation >= 0 ? 1 : -1; currentRotation += deltaRotationSign * Math.min(Math.abs(deltaRotation),this._maxRotationSpeed); this._rotation = currentRotation - 45; } this.ClampPaddleRotation(); }; CPaddle.prototype.ClampPaddleRotation = function() { var deltaRotation = WrapAngle(this._rotation - this._oldRotation); if(deltaRotation >= 0 && IsRightOfHumpLine(this._oldRotation,this._arcLength * 0.5) && !IsRightOfHumpLine(this._rotation,this._arcLength * 0.5)) { this._rotation = Math.min(110,Wrap(this._rotation,0,360)); } else if(deltaRotation <= 0 && IsLeftOfHumpLine(this._oldRotation,this._arcLength * 0.5) && !IsLeftOfHumpLine(this._rotation,this._arcLength * 0.5)) { this._rotation = Math.max(160,this._rotation); } this._oldRotation = this._rotation; }; CPaddle.prototype.PerformAI = function() { if(this._isReceiving || !this._rotationTarget) { var velNormal = new Object(); velNormal.x = this._parent.puck1._velX; velNormal.y = this._parent.puck1._velY; var vecMagnitude = Math.sqrt(velNormal.x * velNormal.x + velNormal.y * velNormal.y); velNormal.x /= vecMagnitude; velNormal.y /= vecMagnitude; var intersectionPoints = FindRayCircleIntersections({origin:{x:this._parent.puck1._x,y:this._parent.puck1._y},direction:{x:velNormal.x,y:velNormal.y}},{center:{x:0,y:0},radius:122}); if(intersectionPoints.length > 0) { this._rotationTarget = Math.atan2(intersectionPoints[0].y,intersectionPoints[0].x) / 3.141592653589793 * 180; } if(this._rotationTarget && !this._isReceiving) { var distFromRotationTarget = Math.abs(this._rotationTarget - this._rotation); if(distFromRotationTarget < this._arcLength * 2) { var randomDirection = Math.random() >= 0.5 ? 1 : -1; var avoidanceTarget = this._rotationTarget + randomDirection * this._arcLength * 2; if(IsRightOfHumpLine(avoidanceTarget) && !IsRightOfHumpLine(this._rotationTarget) || IsLeftOfHumpLine(avoidanceTarget) && !IsLeftOfHumpLine(this._rotationTarget)) { avoidanceTarget = this._rotationTarget + (- randomDirection) * this._arcLength * 2; } this._rotationTarget = avoidanceTarget; } else { this._rotationTarget = null; } } } this.UpdateRotation(); }; CPaddle.prototype.BeginReceiving = function() { this._isReceiving = true; if(this._isAIControlled) { this._englishAngle = Math.random() * 10 - 5; this._rotationTarget = null; } else { this._englishAngle = 0; } }; CPaddle.prototype.FinishedReceiving = function() { this._isReceiving = false; this._rotationTarget = null; };